package com.bussiness.config.annotions;


import com.alibaba.fastjson.JSON;
import com.bussiness.config.util.SystemProperties;
import com.bussiness.system.dao.MyAuthDao;
import com.bussiness.system.dao.MyDeptPostsDao;
import com.bussiness.system.model.MyAuthEntity;
import com.common.response.ResponseBean;
import com.common.response.ResponseCode;
import com.security.auth.UserDetail;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;


/**
 * @author SYSTEM
 * @HasPermission
 * 使用 注解进行权限鉴定
 */
@Aspect
@Component
public class HasPermissionAop {

    Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MyDeptPostsDao myDeptPostsDao;
    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    private MyAuthDao myAuthDao;

    private HttpServletResponse getResponse(){
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse httpServletResponse = servletRequestAttributes.getResponse();
        httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
        return httpServletResponse;
    }


    @Pointcut(value = "@within(com.bussiness.config.annotions.MyRoleAuth)")
    public void pointCut(){}

    /**
     * url+deptid匹配用户当前请求权限是否在这个部门下(现在从security里获取的userId，如果不是security则需要修改)
     * 判断该请求是否已经在资源表里面，如果没有直接通过
     * @author zyj
     * @date 2019/9/25 10:47
     * @param joinPoint
     * @return
     */
    @Around(value = "pointCut()")
    public Object beforeController(ProceedingJoinPoint joinPoint) throws Throwable{
        HttpServletRequest request = this.getRequest();
        String url = request.getRequestURI();

        //step1:判断该路径是否在资源表里面
        List<MyAuthEntity> list = myAuthDao.selectAuth();
        Iterator<MyAuthEntity> ite = list.iterator();
        boolean b = false;
        while (ite.hasNext()){
            String authUrl = ite.next().getUrl();
            if(url.equals(authUrl)){
                b = true;
            }
        }
        if(!b){
            Object object = joinPoint.proceed();
            return object;
        }

        //step2: 如果资源表里有，则判断是否有权限，资源人员：url+":"+userid
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (null != authentication) {
            UserDetail userDetail = (UserDetail)  authentication.getPrincipal();
            long userId = userDetail.getId();
            //系统管理员
            if(userId==systemProperties.getRootId()){
                return joinPoint.proceed();
            }
            Set<String> urlSet = getUrlCode(userId);
            String userKey = url+":"+userId;

            //判断人员权限
            if(urlSet==null||urlSet.isEmpty()||!urlSet.contains(userKey)){
                write();
                return null;
            }

        }
        Object object = joinPoint.proceed();
        return object;
    }

    public void write() throws Exception{
        HttpServletResponse response = getResponse();
        ResponseBean responseBean = new ResponseBean();
        responseBean.setCode(ResponseCode.FORBIDDEN.getValue());
        responseBean.setMessage(ResponseCode.FORBIDDEN.getDescripe());
        response.getWriter().write(JSON.toJSONString(responseBean));
    }

    public HttpServletRequest getRequest(){
        //获取到请求的属性
        ServletRequestAttributes attributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取到请求对象
        return attributes.getRequest();
    }


    public Set<String>  getUrlCode(Long userId){
        List<Map> list = myDeptPostsDao.selectUrlByUserId(userId);
        Iterator<Map> ite = list.iterator();
        Set<String> set = new HashSet<String>();
        while (ite.hasNext()){
            String url = ite.next().get("url").toString();
            set.add(url+":"+userId);
        }

        return null;
    }


}
